﻿using System;
using System.Collections.Generic;
using System.Linq;

using SPDCMScanning.FileSystem.Helpers.Interfaces;

using System.IO;
using System.Security.Permissions;

namespace SPDCMScanning.FileSystem.Helpers
{
    /// <summary>
    /// IO Helpers
    /// </summary>
    public class FileHelper : IFileHelper
    {
        #region private members

        private List<string> _filesFound = new List<string>();

        #endregion

        #region public methods

        /// <summary>
        /// Gets the content of a specific file as byte array.
        /// </summary>
        /// <param name="filePath">Path, which contains all the file.</param>
        /// <param name="fileName">The name of the file</param>
        /// <returns>
        /// byte[] array, containing the contents of the file
        /// </returns>
        public byte[] ReadSingleFileAsByteArray(string filePath, string fileName)
        {
            byte[] fileContent;

            if (String.IsNullOrEmpty((filePath)))
            {
                throw new ArgumentException("Parameter must not be null or empty.", "filePath");
            }
            if (String.IsNullOrEmpty(fileName))
            {
                throw new ArgumentException("Parameter must not be null or empty.", fileName);
            }

            using (FileStream f = new FileStream(Path.Combine(filePath, fileName), FileMode.Open))
            {
                fileContent = new byte[f.Length - 1];

                int read = f.Read(fileContent, 0, ((int)(f.Length - 1)));
            }

            return fileContent;
        }

        /// <summary>
        /// Gets the full path of all files in directory.
        /// </summary>
        /// <param name="directory">The directory.</param>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public List<string> GetFullPathOfAllFilesInDirectory(string directory, string filter)
        {
            if (String.IsNullOrEmpty(directory))
            {
                throw new ArgumentException("Parameter must not be null or empty", "directory");
            }
            if (string.IsNullOrEmpty(filter))
            {
                throw new ArgumentException("Parameter must not be null or empty.", "filter");
            }
            if (!Directory.Exists(directory))
            {
                throw new DirectoryNotFoundException(String.Format("Directory {0}, does not exist", directory));
            }


            List<string> searchPatterns;

            searchPatterns = filter.Split(' ').ToList();

            if (searchPatterns != null && searchPatterns.Count > 1)
            {
                //Multiple Patterns
                this._filesFound = this.GetFiles(directory, searchPatterns);
            }
            else
            {
                //Single Pattern
                this._filesFound = Directory.GetFiles(directory, filter, SearchOption.AllDirectories).ToList<string>();
            }

           
            return this._filesFound;
        }

        /// <summary>
        /// Get all the files in a directory that match
        /// the specified search pattern
        /// </summary>
        /// <param name="path">The directory to seach</param>
        /// <param name="listOfSearchPatterns">the list of search patterns</param>
        /// <returns>The list of files that match the specified pattern</returns>
        public  List<string> GetFiles(string path
            , List<string> listOfSearchPatterns)
        {
            List<string> matchingFiles = new List<string>();

            foreach (string pattern in listOfSearchPatterns)
            {
                //add the the files that match our pattern to our list
                matchingFiles.AddRange(Directory.GetFiles(path, pattern));
            }

            return matchingFiles;
        }

        /// <summary>
        /// Checks if file exists.
        /// </summary>
        /// <param name="fullPathToFile">The full path to file.</param>
        /// <returns></returns>
        public bool CheckIfFileExists(string fullPathToFile)
        {
            if (String.IsNullOrEmpty(fullPathToFile))
            {
                throw new ArgumentException("Parameter must not be null or empty.", fullPathToFile);
            }

            if (File.Exists(fullPathToFile))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Gets the size of the fiel.
        /// </summary>
        /// <param name="fullPathToFile">The full path to file.</param>
        /// <returns></returns>
        public long GetFileSize(string fullPathToFile)
        {
            if (string.IsNullOrEmpty(fullPathToFile))
            {
                throw new ArgumentException("Argument must not be null or empty.", "fullPathToFile");
            }

            if (File.Exists(fullPathToFile))
            {
                return new FileInfo(fullPathToFile).Length;
            }
            throw new FileNotFoundException("File does not exist.", fullPathToFile);
        }

        /// <summary>
        /// Creates the TMP file.
        /// Code taken from
        /// http://www.daveoncsharp.com/2009/09/how-to-use-temporary-files-in-csharp/comment-page-1/#comment-18270
        /// Thank you Dave!
        /// </summary>
        /// <returns></returns>
        private static string CreateTmpFile()
        {
            string fileName;

            try
            {
                // Get the full name of the newly created Temporary file.
                // Note that the GetTempFileName() method actually creates
                // a 0-byte file and returns the name of the created file.
                fileName = Path.GetTempFileName();

                // Craete a FileInfo object to set the file's attributes
                var fileInfo = new FileInfo(fileName);

                // Set the Attribute property of this file to Temporary.
                // Although this is not completely necessary, the .NET Framework is able
                // to optimize the use of Temporary files by keeping them cached in memory.
                fileInfo.Attributes = FileAttributes.Temporary;
            }
            catch (Exception ex)
            {
                throw;
            }

            return fileName;
        }

        #endregion

        #region indexer

        /// <summary>
        /// Gets or sets the <see cref="System.String"/> with the specified i.
        /// </summary>
        public string this[int i]
        {
            get
            {
                return _filesFound[i];
            }
            set
            {
                _filesFound[i] = value;
            }
        }

        #endregion
    }
}